#ifndef __PERSISTENCE_H__
#define __PERSISTENCE_H__

#include <Arduino.h>
#include <Preferences.h>
#include <LittleFS.h>
#include "config.h"

#include "sensors.h"
#include "ptime.h"

// Namespace name is limited to 15 chars.
// Key name is limited to 15 chars.
#define PERSISTENCE_NAMESPACE "paqm_data"
#define PERSISTENCE_KEY_DATA_META_KEY_INDEX "dm_KI"
#define PERSISTENCE_KEY_DATA_META_KEY_BUF "dm_KB"

// 16 bytes
typedef struct
{
  uint16_t tvoc;
  uint16_t eco2;
  float temperature;
  float humidity;
  Timestamp_t timestamp;
} PersistenceData_t;
static const size_t PersistenceDataSize = sizeof(PersistenceData_t);

typedef struct
{
  uint32_t count;
  Timestamp_t first_ts;
  String first_ts_raw; // 原始时间戳字符串
  Timestamp_t last_ts;
  String last_ts_raw; // 原始时间戳字符串
  bool full;
} Persistence_stats_t;

/// deprecated start
/////////////////////////////////////////////////////// v1 perefrence库 
void Persistence_write_entry(const char *key, PersistenceData_t *data);
void Persistence_write_entries(const char *key, PersistenceData_t *data, size_t length);

size_t Persistence_read_entry(const char *key, PersistenceData_t *data);
size_t Persistence_read_entries(const char *key, PersistenceData_t *data, size_t length);

void Persistence_delete_entry(const char *key);

void Persistence_test(void);
PersistenceData_t Persistence_convert(GS_result_t *gs, ES_result_t *es);
char *Persistence_format(PersistenceData_t *data);

/////////////////////////////// app层代码
void Persistence_init();
void Persistence_restore_meta();
void Persistence_write_meta();
void Persistence_write_data(uint32_t ts, GS_result_t *gs, ES_result_t *es);

// 必须外层malloc好传进来
uint32_t Persistence_read_all_data(PersistenceData_t *data);

typedef void (*Persistence_traverse_cb)(uint32_t ts, PersistenceData_t *data, uint32_t count, bool finished);
void Persistence_traverse_all_data(Persistence_traverse_cb cb);

void Persistence_delete_all_data();

Persistence_stats_t Persistence_get_stats();

void Persistence_write_data_test();
/// deprecated end

//////////////////////////////v2 littelfs
class Persistence
{
public:
  Persistence();
  ~Persistence();
  bool init();
  void writeData(Timestamp_t ts, GS_result_t *gs, ES_result_t *es);
  void readAllData();
  void deleteAllData();
  Persistence_stats_t getStats();
  uint32_t getFileCounts();
  void formatFS();

  void Test_Stats();
  void Test_Write();

private:
  String getCurrentFilename();
  void cleanOldFiles();
  void listDir(const char *dirname = "/", uint8_t levels = 0);

  Timestamp_t parseOneLineTs(String line);
  String parseOneLineTsRaw(String line);
  String getSecondLine(const char *path);
  String getLastLine(const char *path);
};

struct FileInfo
{
  String path;
  String name;
  time_t lastWrite;
};

extern Persistence P_LittleFS;

#endif